package cn.ycq.im.controller;

import cn.ycq.im.commons.annotation.Router;
import cn.ycq.im.commons.exceptions.ServiceException;
import cn.ycq.im.commons.utils.FreemarkerRenderUtils;
import cn.ycq.im.commons.utils.Https;
import cn.ycq.im.model.User;
import cn.ycq.im.service.UserService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Controller
@Slf4j
public class UserController {

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private MailProperties mailProperties;

    @Autowired
    private UserService userService;

    private final Map<String,String> emailVcodes = new ConcurrentHashMap<>();

    private ExecutorService executorService = Executors.newCachedThreadPool();

    @Router(method = "post", uri = "/sendEmail")
    public void sendEmail(FullHttpRequest httpRequest, FullHttpResponse response) {
        String requestBodyToString = Https.RequestUtils.getRequestBodyToString((FullHttpRequest) httpRequest);
        JSONObject jsonObject = JSON.parseObject(requestBodyToString);
        String email = jsonObject.getString("email");


        executorService.execute(()->{
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            try {
                mimeMessage.setFrom(new InternetAddress(mailProperties.getUsername(), "IM", CharsetUtil.UTF_8.toString()));
                mimeMessage.setSubject("[IM]邮箱验证码");
                mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(email));

                HashMap<String, Object> props = new HashMap<>();
                String vcode = String.valueOf(new Random().nextInt(899999) + 100000);

                emailVcodes.put(email,vcode);

                props.put("vcode",vcode);
                String render = FreemarkerRenderUtils.render("email-template.html", props);

                MimeBodyPart mimeBodyPart = new MimeBodyPart();
                mimeBodyPart.setContent(render, "text/html;charset=utf-8");

                MimeMultipart mimeMultipart = new MimeMultipart();
                mimeMultipart.addBodyPart(mimeBodyPart);

                mimeMessage.setContent(mimeMultipart);

                javaMailSender.send(mimeMessage);

            } catch (Exception e) {
                log.error("发送邮件失败", e);
            }
        });


        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("code", "200");
        Https.ResponseUtils.writeJSONByObject(response, hashMap);
    }

    @Router(method = "post", uri = "/login")
    public void login(FullHttpRequest httpRequest, FullHttpResponse response) {
        String requestBodyToString = Https.RequestUtils.getRequestBodyToString((FullHttpRequest) httpRequest);
        JSONObject jsonObject = JSON.parseObject(requestBodyToString);
        String vcode = jsonObject.getString("vcode");
        String email = jsonObject.getString("email");
        String vc = emailVcodes.get(email);

        if(!vcode.equals(vc)){
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("code", "500");
            hashMap.put("msg", "验证码错误");
            Https.ResponseUtils.writeJSONByObject(response, hashMap);
            return ;
        }else{
            emailVcodes.remove(email);
        }

        String token = userService.login(email);

        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("code", "200");
        hashMap.put("token", token);
        Https.ResponseUtils.writeJSONByObject(response, hashMap);
    }

    @Router(method = "get", uri = "/getUserInfo")
    public void getUserInfo(FullHttpRequest httpRequest, FullHttpResponse response) {
        String token = httpRequest.headers().get("token");
        if(token == null){

            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("code", "500");
            hashMap.put("msg", "token 不能为空");
            Https.ResponseUtils.writeJSONByObject(response, hashMap);
            return;
        }
        User userInfo = userService.getUserInfo(token);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("code", "200");
        hashMap.put("data", userInfo);
        Https.ResponseUtils.writeJSONByObject(response, hashMap);
    }

    @Router(method = "post", uri = "/setUserInfo")
    public void setUserInfo(FullHttpRequest httpRequest, FullHttpResponse response) {
        JSONObject jsonObject = JSON.parseObject(Https.RequestUtils.getRequestBodyToString(httpRequest));
        String name = jsonObject.getString("name");
        if(name == null){

            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("code", "500");
            hashMap.put("msg", "name 不能为空");
            Https.ResponseUtils.writeJSONByObject(response, hashMap);
            return;
        }

        String token = httpRequest.headers().get("token");
        if(token == null){

            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("code", "500");
            hashMap.put("msg", "token 不能为空");
            Https.ResponseUtils.writeJSONByObject(response, hashMap);
            return;
        }
        try {
            userService.setUserInfo(token,name);
        }catch (ServiceException e){
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("code", "500");
            hashMap.put("msg",e.getMessage());
            Https.ResponseUtils.writeJSONByObject(response, hashMap);
            return;
        }

        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("code", "200");
        hashMap.put("msg","ok");
        Https.ResponseUtils.writeJSONByObject(response, hashMap);
    }

}
